import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;

import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleWeightedGraph;


/**
 * Class Markov Clustering
 * @author liat
 * Last updater: Liat
 * Date: 6.08.09 18:00
 * Description: Part a given network into clusters according to the MCL algorithm.
 */
public class MarkovClustring extends ClusteringAlgorithms{

	private String EDGES_FILE_NAME = "netDataFile.txt";
	private String CLUSTERS_FILE = "clusters.out";
	
	/**
	 * Constructor
	 */
	public MarkovClustring() {
		super("netDataFile.txt");
	}

	/**
	 * Returns a list of clusters generated by MCL algorithm.
	 */
	public LinkedList<Cluster> getClusters(SimpleWeightedGraph<String, DefaultWeightedEdge> net,
															  HashMap<String, Gene> geneMap) {
		// This is the name of the file that contains data on the
		// edges of the network. It is the input for the mcl algorithm.
		
		writeNetworkFile(net);
		LinkedList<Cluster> clusterList = getMCLClusters(geneMap);
		return clusterList;
	}


	


	/**
	 * Runs the mcl command to compute the clusters of the network.
	 * Afterwards reads the output file "clusters.out" 
	 * and extracts the clusters from it.
	 * @param edgesFileName contains the edges of the network.
	 * @param clustersFile contains the clusters generated by mcl.
	 * @param net the network we wish to part to clusters.
	 * @return a list of clusters generated by MCL algorithm.
	 */
	private LinkedList<Cluster> getMCLClusters(HashMap<String, Gene> geneMap) {
		LinkedList<Cluster> clusters = new LinkedList<Cluster>();
		String line;
		Cluster cluster;
		String[] protNames;
		BufferedReader read;
		// first run MCL algorithm
		Runtime run = Runtime.getRuntime();
		Process runMCL;
		File curDir = new File(".");
		//System.out.println("current dir:"+curDir.getAbsolutePath());
		// This is the command to run mcl.
//		String[] command ={ Consts.MCL_DIR+"mcl", Consts.CUR_DIR+EDGES_FILE_NAME ,"--abc","-o",Consts.CUR_DIR+CLUSTERS_FILE}; // TEMP TODO liat version
		// Oded version
		String[] command ={ Consts.MCL_DIR+"mcl", Consts.DATA_DIR +EDGES_FILE_NAME ,"--abc","-o",Consts.DATA_DIR+CLUSTERS_FILE};		
		try {
			//run.exec(moveToDir); // move to the directory of MCL
			runMCL = run.exec(command);
			runMCL.waitFor();
			//MCLoutput = runMCL.getOutputStream();
			//System.out.println(MCLoutput);
		} catch (InterruptedException ine) {
			System.err.println("Running MCL is interrupted by another thread");
		} catch (IOException ioe) {
			System.err.println("Can't execute mcl since:");
			System.err.println(ioe.getMessage());
			System.exit(1);
		}
		// read the clusters from the output file:
		try {
			// read = new BufferedReader(new FileReader(Consts.CUR_DIR+CLUSTERS_FILE)); // TEMP TODO liat version
			read = new BufferedReader(new FileReader(Consts.DATA_DIR+CLUSTERS_FILE));
			while ((line = read.readLine()) != null) {
				protNames = line.split("\t");
				if (protNames.length > 1) {
					cluster = generateCluster(protNames, geneMap);
					clusters.add(cluster);
				}
				
			}
			read.close();
		} catch (IOException ioe) {
			System.err.println("Can't read the clusters file since: ");
			System.err.println(ioe.getMessage());
			System.exit(1);
		}
		return clusters;
	}
}
